﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Security.Principal;
using System.Text;
using FlexiCommerce.Configuration;

namespace FlexiCommerce.Security
{
    public class SecurityManager : ISecurityManager
    {

        private Web.IWebContext webContext;

        //private bool enabled = true;
        private bool enabled = true;
        string[] systemadminNames = new string[] { "Admin" };
        string[] systemadminRoles = new string[] { "Administrators" };
        string[] marketingmanagerNames = new string[] { "Marketer" };
        string[] marketingmanagerRoles = new string[] { "MarketingManagers" };
        string[] catalogmanagerNames = new string[] { "CatalogManager" };
        string[] catalogmanagerRoles = new string[] { "CatalogManagers" };
        string[] ordermanagerNames = new string[] { "OrderManager" };
        string[] ordermanagerRoles = new string[] { "OrderManagers" };

        public SecurityManager(Web.IWebContext webContext, SecuritySection config)
        {
            this.webContext = webContext;

            if (config.SystemAdministrators.Users != null)
                SystemAdminNames = ToArray(config.SystemAdministrators.Users);
            if (config.SystemAdministrators.Roles != null)
                SystemAdminRoles = ToArray(config.SystemAdministrators.Roles);

            if (config.MarketingManagers.Users != null)
                MarketingManagerNames = ToArray(config.MarketingManagers.Users);
            if (config.MarketingManagers.Roles != null)
                MarketingManagerRoles = ToArray(config.MarketingManagers.Roles);

            if (config.OrderManagers.Users != null)
                OrderManagerNames = ToArray(config.OrderManagers.Users);
            if (config.OrderManagers.Roles != null)
                OrderManagerRoles = ToArray(config.OrderManagers.Roles);

            if (config.CatalogManagers.Users != null)
                CatalogManagerNames = ToArray(config.CatalogManagers.Users);
            if (config.CatalogManagers.Roles != null)
                CatalogManagerRoles = ToArray(config.CatalogManagers.Roles);
        }

        private static string[] ToArray(StringCollection list)
        {
            string[] array = new string[list.Count];
            list.CopyTo(array, 0);
            return array;
        }

        #region Properties

        public string[] SystemAdminNames
        {
            get { return systemadminNames; }
            set { systemadminNames = value; }
        }

        public string[] SystemAdminRoles
        {
            get { return systemadminRoles; }
            set { systemadminRoles = value; }
        }

        public string[] MarketingManagerNames
        {
            get { return marketingmanagerNames; }
            set { marketingmanagerNames = value; }
        }
        public string[] MarketingManagerRoles
        {
            get { return marketingmanagerRoles; }
            set { marketingmanagerRoles = value; }
        }
        public string[] OrderManagerNames
        {
            get { return ordermanagerNames; }
            set { ordermanagerNames = value; }
        }
        public string[] OrderManagerRoles
        {
            get { return ordermanagerRoles; }
            set { ordermanagerRoles = value; }
        }
        public string[] CatalogManagerNames
        {
            get { return catalogmanagerNames; }
            set { catalogmanagerNames = value; }
        }
        public string[] CatalogManagerRoles
        {
            get { return catalogmanagerRoles; }
            set { catalogmanagerRoles = value; }
        }

        ///// <summary>Gets or sets whether the security manager is enabled.</summary>
        //public virtual bool Enabled
        //{
        //    get { return enabled; }
        //    set { enabled = value; }
        //}

        ///// <summary>Gets or sets whether the security manager is enabled in the current scope. This can be used to override the security features in certain situations.</summary>
        //public virtual bool ScopeEnabled
        //{
        //    get
        //    {
        //        return !webContext.RequestItems.Contains("SecurityManager.ScopeEnabled");
        //    }
        //    set
        //    {
        //        if (value && webContext.RequestItems.Contains("SecurityManager.ScopeEnabled"))
        //            webContext.RequestItems.Remove("SecurityManager.ScopeEnabled");
        //        else if (!value)
        //            webContext.RequestItems["SecurityManager.ScopeEnabled"] = false;
        //    }
        //}
        #endregion

        #region Methods


        private bool HasName(IPrincipal user, string[] names)
        {
            foreach (string name in names)
                if (user.Identity.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
                    return true;
            return false;
        }

        private bool IsInRole(IPrincipal user, string[] roles)
        {
            foreach (string role in roles)
                if (user.IsInRole(role))
                    return true;
            return false;
        }

        public bool IsAuthorized(IPrincipal user, IEnumerable<string> roles)
        {
            foreach (string role in roles)
                if (user.IsInRole(role))
                    return true;
            return false;
        }

        #endregion

        public bool IsSystemAdmin(IPrincipal user)
        {
            if (user == null)
                return false;
            else
                return HasName(user, this.SystemAdminNames) || IsInRole(user, this.SystemAdminRoles);
        }


        public bool IsMarketingManager(IPrincipal user)
        {
            if (user == null)
                return false;
            if (IsSystemAdmin(user))
                return true;
            else
                return HasName(user, this.MarketingManagerNames) || IsInRole(user, this.MarketingManagerRoles);
        }

        public bool IsCatalogManager(IPrincipal user)
        {
            if (user == null)
                return false;
            if (IsSystemAdmin(user))
                return true;
            else
                return HasName(user, this.CatalogManagerNames) || IsInRole(user, this.CatalogManagerRoles);
        }

        public bool IsOrderManager(IPrincipal user)
        {
            if (user == null)
                return false;
            if (IsSystemAdmin(user))
                return true;
            else
                return HasName(user, this.OrderManagerNames) || IsInRole(user, this.OrderManagerRoles);
        }



        #region ISecurityManager Members


      

        #endregion

        #region ISecurityManager Members


        /// <summary>Gets or sets whether the security manager is enabled.</summary>
        public virtual bool Enabled
        {
            get { return enabled; }
            set { enabled = value; }
        }

        /// <summary>Gets or sets whether the security manager is enabled in the current scope. This can be used to override the security features in certain situations.</summary>
        public virtual bool ScopeEnabled
        {
            get
            {
                return !webContext.RequestItems.Contains("ItemSecurityManager.ScopeEnabled");
            }
            set
            {
                if (value && webContext.RequestItems.Contains("ItemSecurityManager.ScopeEnabled"))
                    webContext.RequestItems.Remove("ItemSecurityManager.ScopeEnabled");
                else if (!value)
                    webContext.RequestItems["ItemSecurityManager.ScopeEnabled"] = false;
            }
        }


        #endregion
    }
}
